package com.ssy.lingxi.after.sale.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.ssy.lingxi.after.sale.entity.ReplaceDeliveryGoodsDO;
import com.ssy.lingxi.after.sale.entity.ReplaceDeliveryGoodsDetailDO;
import com.ssy.lingxi.after.sale.entity.ReplaceGoodsDO;
import com.ssy.lingxi.after.sale.entity.ReplaceGoodsDetailAssociatedDO;
import com.ssy.lingxi.after.sale.model.constant.ReplaceDeliveryGoodsStatusEnum;
import com.ssy.lingxi.after.sale.model.constant.ReplaceDeliveryGoodsTypeEnum;
import com.ssy.lingxi.after.sale.model.constant.ReturnDeliveryGoodsStatusEnum;
import com.ssy.lingxi.after.sale.model.vo.request.CommodityPageVO;
import com.ssy.lingxi.after.sale.model.vo.response.AssociatedProductVO;
import com.ssy.lingxi.after.sale.model.vo.response.CommodityQueryVO;
import com.ssy.lingxi.after.sale.model.vo.response.DeliveryGoodsDetailVO;
import com.ssy.lingxi.after.sale.model.vo.response.DeliveryGoodsVO;
import com.ssy.lingxi.after.sale.repository.ReplaceDeliveryGoodsDetailRepository;
import com.ssy.lingxi.after.sale.repository.ReplaceDeliveryGoodsRepository;
import com.ssy.lingxi.after.sale.repository.ReplaceGoodsDetailMaterielRepository;
import com.ssy.lingxi.after.sale.repository.ReplaceGoodsRepository;
import com.ssy.lingxi.after.sale.service.IFeignService;
import com.ssy.lingxi.after.sale.service.IReplaceDeliveryGoodsService;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.logistics.api.dto.response.LogisticsOrderFeignResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 换货发货接口实现
 * @author 伍将
 * @date 2020/11/30
 * @version 2.0.0
 */
@Service
public class ReplaceDeliveryGoodsServiceImpl implements IReplaceDeliveryGoodsService {

    @Resource
    private ReplaceDeliveryGoodsRepository repository;

    @Resource
    private ReplaceGoodsRepository replaceGoodsRepository;

    @Resource
    private ReplaceDeliveryGoodsDetailRepository replaceDeliveryGoodsDetailRepository;

    @Resource
    private IFeignService feignService;
    @Resource
    private ReplaceGoodsDetailMaterielRepository replaceGoodsDetailMaterielRepository;
    /**
     * 获取发货列表
     * @param replaceId 换货id
     * @param deliveryType 发货类型：1-退货 2-换货
     * @return 发货VO列表
     */
    @Override
    public List<DeliveryGoodsVO> getDeliveryList(Long replaceId, Integer deliveryType, Boolean isSupplier) {

        List<DeliveryGoodsVO> resultList = null;

        List<ReplaceDeliveryGoodsDO> deliveryGoodsDOList = repository.findByReplaceIdAndReplaceDeliveryTypeOrderByBatchNo(replaceId, deliveryType);
        List<Long> logisticsIds = deliveryGoodsDOList.stream().map(ReplaceDeliveryGoodsDO::getLogisticsId).filter(Objects::nonNull).collect(Collectors.toList());
        Map<Long, LogisticsOrderFeignResponse> logisticsInfoByIds = feignService.listLogisticsOrderMap(logisticsIds);
        if (!CollectionUtils.isEmpty(deliveryGoodsDOList)) {
            resultList = deliveryGoodsDOList.stream().map(r -> {
                DeliveryGoodsVO queryVO = new DeliveryGoodsVO();
                queryVO.setDeliveryId(r.getId());
                queryVO.setBatch(r.getBatchNo());
                queryVO.setDeliveryNoId(r.getId());
                queryVO.setDeliveryNo(r.getDeliveryOrderNo());
                queryVO.setDeliveryTime(DateUtil.format(DateUtil.date(r.getDeliveryTime()), "yyyy-MM-dd HH:mm"));
                queryVO.setLogisticsName(r.getLogisticsName());
                queryVO.setLogisticsOrderNo(r.getLogisticsOrderNo());
                queryVO.setLogisticsId(r.getLogisticsId());
                queryVO.setStorageId(r.getStorageId());
                queryVO.setStorageNo(r.getStorageNo());
                queryVO.setStorageTime(r.getStorageTime() != null && r.getStorageTime() > 0 ? DateUtil.format(DateUtil.date(r.getStorageTime()), "yyyy-MM-dd HH:mm") : "");
                queryVO.setInnerStatus(r.getStatus());
                if (ReplaceDeliveryGoodsTypeEnum.REPLACE_GOODS.getCode().equals(deliveryType)) {
                    queryVO.setInnerStatusName(ReplaceDeliveryGoodsStatusEnum.getMessage(r.getStatus(), isSupplier));
                } else {
                    queryVO.setInnerStatusName(ReturnDeliveryGoodsStatusEnum.getMessage(r.getStatus(), isSupplier));
                }
                //查询物流单信息
                if(r.getLogisticsId()!=null&&logisticsInfoByIds!=null){
                    LogisticsOrderFeignResponse logisticsOrderData = logisticsInfoByIds.get(r.getLogisticsId());
                    if(logisticsOrderData!=null) {
                        queryVO.setLogisticsReceiveAddress(logisticsOrderData.getReceiverFullAddress());
                        queryVO.setLogisticsReceiveAddressId(logisticsOrderData.getReceiverAddressId());
                    }
                }
                //查询关联商品信息
                List<Long> detailIds = r.getDetailList().stream().filter(o ->o.getReplaceGoodsDetailDO()!=null).map(o -> o.getReplaceGoodsDetailDO().getId()).collect(Collectors.toList());
                List<ReplaceGoodsDetailAssociatedDO> associatedDOList = replaceGoodsDetailMaterielRepository.findAllByReplaceDetailIdIn(detailIds);
                Map<Long,ReplaceGoodsDetailAssociatedDO> detailMap=null;
                if(CollectionUtil.isNotEmpty(associatedDOList)){
                    detailMap = associatedDOList.stream().collect(Collectors.toMap(ReplaceGoodsDetailAssociatedDO::getReplaceDetailId, v -> v));
                }
                //发货明细
                List<DeliveryGoodsDetailVO> detailList =new ArrayList<>();
                for(ReplaceDeliveryGoodsDetailDO o:r.getDetailList()) {
                    DeliveryGoodsDetailVO detail = new DeliveryGoodsDetailVO();
                    detail.setOrderNo(o.getOrderNo());
                    detail.setProductId(o.getProductId());
                    detail.setProductName(o.getProductName());
                    detail.setCategory(o.getCategory());
                    detail.setBrand(o.getBrand());
                    detail.setUnit(o.getUnit());
                    detail.setCount(o.getReplaceCount());
                    detail.setDeliveryCount(o.getDeliveryCount());
                    detail.setStorageCount(o.getStorageCount());
                    detail.setDifferenceCount(NumberUtil.sub(o.getDeliveryCount() , o.getStorageCount()));
                    detail.setSkuPic(o.getSkuPic());
                    if(detailMap!=null) {
                        ReplaceGoodsDetailAssociatedDO associatedDO = detailMap.get(o.getReplaceGoodsDetailDO().getId());
                        if(associatedDO!=null){
                            AssociatedProductVO associatedProductVO=new AssociatedProductVO();
                            BeanUtils.copyProperties(associatedDO,associatedProductVO);
                            detail.setAssociatedProductVO(associatedProductVO);
                        }
                    }
                    detailList.add(detail);
                }
                queryVO.setDetailList(detailList);

                return queryVO;
            }).collect(Collectors.toList());
        }

        return resultList;
    }

    /**
     * 物流服务获取退货商品
     * @author 伍将
     * @date 2020/12/8
     * @param pageVO:
     * @return 退货商品
     **/
    @Override
    public Wrapper<PageData<CommodityQueryVO>> pageReturnCommodityByLogistics(CommodityPageVO pageVO) {
        return pageCommodityByLogistics(pageVO, ReplaceDeliveryGoodsTypeEnum.RETURN_GOODS.getCode());
    }

    /**
     * 物流服务获取换货商品
     * @author 伍将
     * @date 2020/12/8
     * @param pageVO:
     * @return 取换货商品
     **/
    @Override
    public Wrapper<PageData<CommodityQueryVO>> pageReplaceCommodityByLogistics(CommodityPageVO pageVO) {
        return pageCommodityByLogistics(pageVO, ReplaceDeliveryGoodsTypeEnum.REPLACE_GOODS.getCode());
    }

    /**
     * 物流服务获取退货/换货商品
     * @author 伍将
     * @date 2020/12/8
     * @param pageVO:
     * @param deliveryType:
     * @return 退货/换货商品
     **/
    private Wrapper<PageData<CommodityQueryVO>> pageCommodityByLogistics(CommodityPageVO pageVO, Integer deliveryType) {
        ReplaceGoodsDO replaceDO = replaceGoodsRepository.findById(pageVO.getDataId()).orElse(null);
        if (replaceDO == null) {
            throw new BusinessException(ResponseCode.AS_REPLACE_GOODS_NOT_EXIST);
        }

        Integer batch = 0;
        if (ReplaceDeliveryGoodsTypeEnum.RETURN_GOODS.getCode().equals(deliveryType)) {
            batch = replaceDO.getReturnBatch();
        } else if (ReplaceDeliveryGoodsTypeEnum.REPLACE_GOODS.getCode().equals(deliveryType)) {
            batch = replaceDO.getReplaceBatch();
        }

        ReplaceDeliveryGoodsDO deliveryGoodsDO = repository.findByReplaceIdAndBatchNoAndReplaceDeliveryType(replaceDO.getId(), batch, deliveryType);
        if (deliveryGoodsDO == null) {
            throw new BusinessException(ResponseCode.AS_REPLACE_DELIVERY_GOODS_NOT_EXIST);
        }

        // step 1: 组装查询条件
        Specification<ReplaceDeliveryGoodsDetailDO> spec =  (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("deliveryGoods").get("id").as(Long.class), deliveryGoodsDO.getId()));
            if (StringUtils.hasLength(pageVO.getBrand())) {
                list.add(criteriaBuilder.like(root.get("brand").as(String.class), "%" + pageVO.getBrand().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getCategory())) {
                list.add(criteriaBuilder.like(root.get("category").as(String.class), "%" + pageVO.getCategory().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getProductName())) {
                list.add(criteriaBuilder.like(root.get("productName").as(String.class), "%" + pageVO.getProductName().trim() + "%"));
            }
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // step 2: 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("id").descending());

        // step 3: 分页查询数据
        Page<ReplaceDeliveryGoodsDetailDO> result = replaceDeliveryGoodsDetailRepository.findAll(spec, page);

        // step 4: 组装返回数据
        List<CommodityQueryVO> resultList = result.getContent().stream().map(r -> {
            CommodityQueryVO queryVO = new CommodityQueryVO();
            queryVO.setId(r.getId());
            queryVO.setOrderNo(r.getOrderNo());
            queryVO.setProductId(r.getProductId());
            queryVO.setProductName(r.getProductName());
            queryVO.setCategory(r.getCategory());
            queryVO.setBrand(r.getBrand());
            queryVO.setUnit(r.getUnit());
            return queryVO;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(result.getTotalElements(), resultList));
    }
}
